<template>
  <div style="display: flex; position: relative">
    <div
      class="box"
      :style="minImgBoxStyle"
      @mouseleave="mouseLeave"
      @mouseenter="mouseEnter"
      @mousemove="mousemove($event)"
    >
      <img
        :style="minImgStyle"
        fit="contain"
        ref="minImg"
        :src="finalMinIMGsrc"
      />
      <div v-show="show" class="areaMark" :style="areaMarkStyle"></div>
    </div>
    <div class="box maxImgBox" :style="maxImgBoxStyle" v-show="show">
      <img :style="maxImgStyle" fit="contain" :src="finalMaxIMGsrc" />
    </div>
  </div>
</template>
<script>
export default {
  props: {
    minIMGsrc: String,
    maxIMGsrc: String,
    scale: {
      type: Number,
      default: 2,
    },
    width: {
      type: Number,
      default: 400,
    },
    height: {
      type: Number,
      default: 400,
    },
  },
  data() {
    return {
      show: false,
      finalMinIMGsrc: "",
      finalMaxIMGsrc: "",
      imgBoxWidth: 400,
      imgBoxHeight: 400,
      areaWidth: 200,
      areaHeight: 200,
      areaMarkStyle: {},
      minImgBoxStyle: {
        cursor: "move",
      },
      minImgStyle: {},
      maxImgBoxStyle: {},
      maxImgStyle: {
        position: "absolute",
      },
    };
  },
  watch: {
    immediate: true,
    minIMGsrc() {
      this.init();
    },
    maxIMGsrc() {
      this.init();
    },
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.imgBoxWidth = this.width;
      this.imgBoxHeight = this.height;
      this.$set(this.minImgStyle, "width", this.imgBoxWidth + "px");
      this.$set(this.minImgStyle, "height", this.imgBoxHeight + "px");
      this.$set(this.maxImgStyle, "width", this.imgBoxWidth + "px");
      this.$set(this.maxImgStyle, "height", this.imgBoxHeight + "px");
      this.$set(this.minImgBoxStyle, "width", this.imgBoxWidth + "px");
      this.$set(this.minImgBoxStyle, "height", this.imgBoxHeight + "px");
      this.$set(this.maxImgBoxStyle, "width", this.imgBoxWidth + "px");
      this.$set(this.maxImgBoxStyle, "height", this.imgBoxHeight + "px");
      this.$set(this.maxImgBoxStyle, "left", this.imgBoxWidth + "px");
      this.areaWidth = this.imgBoxWidth / this.scale;
      this.areaHeight = this.imgBoxHeight / this.scale;
      this.finalMinIMGsrc = this.minIMGsrc;
      if (!this.maxIMGsrc) {
        this.finalMaxIMGsrc = this.minIMGsrc;
      }
      this.$set(this.areaMarkStyle, "width", this.areaWidth + "px");
      this.$set(this.areaMarkStyle, "height", this.areaHeight + "px");
      this.$set(this.maxImgStyle, "transform", "scale(" + this.scale + ")");
    },
    mouseEnter() {
      this.show = true;
    },
    mouseLeave() {
      this.show = false;
    },
    mousemove(e) {
      let documentScrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      let mouseClientX = e.clientX;
      let mouseClientY = e.clientY;
      let minImgPosition = this.$refs.minImg.getBoundingClientRect();
      let minImgX = minImgPosition.left;
      let minImgY = minImgPosition.top;
      let areaLeft = mouseClientX - minImgX - this.areaWidth / 2;
      let areaTop = mouseClientY - minImgY - this.areaHeight / 2;
      if (documentScrollTop > 0) {
        areaTop = documentScrollTop + areaTop;
      }
      let minLeft = 0;
      let maxLeft = this.imgBoxWidth - this.areaWidth;
      let minTop = 0;
      let maxTop = this.imgBoxHeight - this.areaHeight;
      if (areaLeft < minLeft) {
        areaLeft = minLeft;
      }
      if (areaLeft > maxLeft) {
        areaLeft = maxLeft;
      }
      if (areaTop < minTop) {
        areaTop = minTop;
      }
      if (areaTop > maxTop) {
        areaTop = maxTop;
      }
      this.$set(this.areaMarkStyle, "left", areaLeft + "px");
      this.$set(this.areaMarkStyle, "top", areaTop + "px");
      this.$set(
        this.maxImgStyle,
        "left",
        ((this.scale - 1) * this.imgBoxWidth) / 2 - areaLeft * this.scale + "px"
      );
      this.$set(
        this.maxImgStyle,
        "top",
        ((this.scale - 1) * this.imgBoxWidth) / 2 - areaTop * this.scale + "px"
      );
    },
  },
};
</script>
<style scoped>
.box {
  border: 1px solid darkgray;
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
}

.areaMark {
  position: absolute;
  background-color: rgba(0, 0, 0, 0.5);
}
.maxImgBox {
  position: absolute;
  z-index: 999999;
}
</style>